package com.kevin.table;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;

import org.apache.commons.lang3.StringUtils;

import com.kevin.enums.BreakOp;
import com.kevin.enums.RowOp;
import com.kevin.extension.MFieldRow;
import com.kevin.utils.StringRegex;
import com.kevin.utils.common.KnCommonUtils;

public class MDataRow implements List<MDataCell> {
	public MDataRow(){
		cellList = new ArrayList<MDataCell>();
	}
	
	public MDataRow(MDataTable dt) {
		if(dt!= null){
			this.table = dt;
			cellList = new ArrayList<MDataCell>(dt.getColumns().size());
		}
	}
	
	 public MDataRow(MDataColumn mdc)
     {
		 cellList = new ArrayList<MDataCell>(mdc.size());
		 getTable().getColumns().addRange(mdc);
     }
	/**
	 * 数据表名称
	 */
	private String tableName;
	/**
	 * 连接字符串
	 */
	private String executorName; 
	/**
	 * table
	 */
	private MDataTable table;
	
    /**
     * 从别的行加载值
     * @param row
     */
    public void loadFrom(MDataRow row)
    {
        loadFrom(row, RowOp.NONE, size() == 0);
    }
	
    /**
     * 从别的行加载值
     * @param row
     * @param rowOp
     * @param isAllowAppendColumn
     */
    public void loadFrom(MDataRow row, RowOp rowOp, boolean isAllowAppendColumn)
    {
        loadFrom(row, rowOp, isAllowAppendColumn, true);
    }
	
	/**
	 * 从别的行加载值
	 * @param row
	 * @param rowOp
	 * @param isAllowAppendColumn
	 * @param isWithValueState
	 */
	public void loadFrom(MDataRow row, RowOp rowOp, boolean isAllowAppendColumn, boolean isWithValueState)
    {
        if (row != null)
        {
            if (isAllowAppendColumn)
            {
                for (int i = 0; i < row.size(); i++)
                {
                    if (!getColumns().contains(row.get(i).getColumnName()))
                    {
                        getColumns().add(row.get(i).getCellstruct());
                    }
                }
            }
            MDataCell rowCell;
            for (MDataCell cell : this)
            {
                rowCell = row.get(cell.getColumnName());
                if (rowCell == null)
                {
                    continue;
                }
                if (rowOp == RowOp.NONE || (!rowCell.isNull() && rowCell.getState() >= rowOp.getKey()))
                {               	
                	cell.setValue(rowCell.getValue());//用属于赋值，因为不同的架构，类型若有区别如 int[access] int64[sqlite]，在转换时会出错
                    //cell._CellValue.IsNull = rowCell._CellValue.IsNull;//
                    if (isWithValueState)
                    {
                    	cell.setState(rowCell.getState());
                    }
                }
            }

        }
    }
	/**
	 * 单元格列表
	 */	
	private ArrayList<MDataCell> cellList;
	
	private ArrayList<MDataCell> jointPrimaryCell;
	public ArrayList<MDataCell> getJointPrimaryCell(){
		if (jointPrimaryCell == null && getColumns().size() > 0)
        {
			jointPrimaryCell = new ArrayList<MDataCell>(getColumns().getJointPrimary().size());
            for (MCellStruct st : getColumns().getJointPrimary())
            {
            	jointPrimaryCell.add(this.get(st.getColumnName()));
            }
        }
        return jointPrimaryCell;
	}

    /**
     * 获取第一个关键主键列
     */
    public MDataCell getPrimaryCell()
    {
        return getJointPrimaryCell().get(0);
    }
	public MDataColumn getColumns(){
		return getTable().getColumns();
	}
	
	public String getTableName() {
        if (table != null)
        {
            return table.getTableName();
        }
        return tableName;
	}
	public void setTableName(String tableName) {
        if (table != null)
        {
        	table.setTableName(tableName);
        }
    	this.tableName = tableName;
	}
//	public String getExecutorName() {
//		if(table != null){
//			return table.getExecutorName();
//		}else if(StringUtils.isEmpty(executorName)){
//			return ExecutorFactory.getDefaultExecutorName();
//		}
//		return executorName;
//	}
//	public void setExecutorName(String executorName) {
//		if(table != null){
//			table.setExecutorName(executorName);
//		}else{
//			this.executorName = executorName;
//		}
//	}

	public MDataTable getTable() {
		if(table == null){
			table = new MDataTable(tableName);
			if(size()>0){
				for (MDataCell cell : this) {
					table.getColumns().add(cell.getCellstruct());
				}
			}
			table.getRows().add(this);
		}	
		return table;
	}
	public void setTable(MDataTable table) {
		this.table = table;
	}
	public ArrayList<MDataCell> getCellList() {
		if(cellList.size() == 0 && table != null && table.getColumns().size() > 0){
			MCellStruct struct;
			for (MCellStruct item : table.getColumns()) {				
				struct = item;
				MDataCell cell = new MDataCell(struct,null);
				cellList.add(cell);
			}
		}
		return cellList;
	}
	public void setCellList(ArrayList<MDataCell> cellList) {
		this.cellList = cellList;
	}

	
    /**
     * 将行的数据行的状态全部重置
     * @param state 状态[0:未更改；1:已赋值,值相同[可插入]；2:已赋值,值不同[可更新]]
     * @return
     */
    public MDataRow resetState(int state)
    {
        return resetState(state, BreakOp.NONE);
    }
	
    /**
     * 将行的数据行的状态全部重置
     * @param state 状态[0:未更改；1:已赋值,值相同[可插入]；2:已赋值,值不同[可更新]]
     * @param op 状态设置选项
     * @return
     */
    public MDataRow resetState(int state, BreakOp op)
    {
        return resetState(state, op, StringUtils.EMPTY);
    }
	
	/**
	 * 批量指定某些列
	 * @param state 状态[0:未更改；1:已赋值,值相同[可插入]；2:已赋值,值不同[可更新]]
	 * @param op 状态设置选项
	 * @param columns 指定的列  多列逗号间隔  column,column,column
	 * @return
	 */
	public MDataRow resetState(int state, BreakOp op, String columns)
    {
        if (StringUtils.isNotEmpty(columns))
        {
            String[] items = StringUtils.strip(columns, ", ").split(",");
            for (int i = 0; i < items.length; i++)
            {
                MDataCell cell = this.get(items[i]);
                if (cell != null)
                {
                    resetState(state, op, cell);
                }
            }
        }
        else
        {
            for (int i = 0; i < this.size(); i++)
            {
                resetState(state, op, this.get(i));
            }
        }
        return this;
    }
	
	private void resetState(int state, BreakOp op, MDataCell cell)
    {
        switch (op)
        {
            case NULL:
                if (cell.isNull())
                {
                    return;
                }
                break;
            case EMPTY:
                if (cell.getStringValue().equals(StringUtils.EMPTY))
                {
                    return;
                }
                break;
            case NULLOREMPTY:
                if (cell.isEmpty())
                {
                    return;
                }
                break;
		default:
	        cell.setState(state);
			break;
        }
    }
	
	public <T> T get(Object key,Class<T> t){	
		return get(key, KnCommonUtils.<T>getDefault(t), t);
    } 
	
	public <T> T get(Object key,T defaultValue,Class<T> t){
		MDataCell cell = get(key);
		if(cell == null || cell.isNull()){
			return defaultValue;
		}
		return cell.get(t);
    } 
	
	@Override
	public boolean add(MDataCell e) {
		// TODO Auto-generated method stub
		return cellList.add(e);
	}

	@Override
	public void add(int index, MDataCell element) {
		// TODO Auto-generated method stub
		cellList.add(index, element);
	}

	@Override
	public boolean addAll(Collection<? extends MDataCell> c) {
		// TODO Auto-generated method stub
		return cellList.addAll(c);
	}

	@Override
	public boolean addAll(int index, Collection<? extends MDataCell> c) {
		// TODO Auto-generated method stub
		return cellList.addAll(index, c);
	}

	@Override
	public void clear() {
		// TODO Auto-generated method stub
		cellList.clear();
	}

	@Override
	public boolean contains(Object o) {
		// TODO Auto-generated method stub
		return cellList.contains(o);
	}

	@Override
	public boolean containsAll(Collection<?> c) {
		// TODO Auto-generated method stub
		return cellList.containsAll(c);
	}

	@Override
	public MDataCell get(int index) {
		return getCellList().get(index);
	}

	/**
	 * 根据列名获取当前行中单元格数据
	 * @param columnName
	 * @return
	 */
	public MDataCell get(String columnName){
		int index = -1;
        if (columnName.length() <= String.valueOf(getCellList().size()).length()) //2<=20
        {
            //判断是否为数字。
        	if(!StringRegex.isInteger(columnName)){
        		index = -1;
        	}
        }
        if (index == -1)
        {
            index = getColumns().indexOf(columnName);//重新检测列是否一致。
        }
        if (index > -1)
        {
            return this.get(index);
        }
        return null;
	}
	
	public MDataCell get(Object field){
	    if (field instanceof Integer)
	    {
	        int index = (Integer)field;
	        if (size() > index)
	        {
	            return get(index);
	        }
	    }
	    else if (field instanceof String)
	    {
	        return get((String)field);
	    }
	    else if (field instanceof MFieldRow)
	    {
	    	MFieldRow iFiled = (MFieldRow)field;
	        if (iFiled.getColID() > -1)
	        {
	            return get(iFiled.getColID());
	        }
	        return get(iFiled.getName());
	    }
	    return get(field.toString());    
    }
	
	@Override
	public int indexOf(Object o) {
		// TODO Auto-generated method stub
		return cellList.indexOf(o);
	}

	@Override
	public boolean isEmpty() {
		// TODO Auto-generated method stub
		return cellList.isEmpty();
	}

	@Override
	public Iterator<MDataCell> iterator() {
		// TODO Auto-generated method stub
		return cellList.iterator();
	}

	@Override
	public int lastIndexOf(Object o) {
		// TODO Auto-generated method stub
		return cellList.lastIndexOf(o);
	}

	@Override
	public ListIterator<MDataCell> listIterator() {
		// TODO Auto-generated method stub
		return cellList.listIterator();
	}

	@Override
	public ListIterator<MDataCell> listIterator(int index) {
		// TODO Auto-generated method stub
		return cellList.listIterator(index);
	}

	@Override
	public boolean remove(Object o) {
		// TODO Auto-generated method stub
		return cellList.remove(o);
	}

	@Override
	public MDataCell remove(int index) {
		// TODO Auto-generated method stub
		return cellList.remove(index);
	}

	@Override
	public boolean removeAll(Collection<?> c) {
		// TODO Auto-generated method stub
		return cellList.removeAll(c);
	}

	@Override
	public boolean retainAll(Collection<?> c) {
		// TODO Auto-generated method stub
		return cellList.retainAll(c);
	}

	@Override
	public MDataCell set(int index, MDataCell element) {
		// TODO Auto-generated method stub
		return cellList.set(index, element);
	}

	public MDataRow set(Object key,Object value,int state){
		MDataCell cell = get(key);
        if (cell != null)
        {
            cell.setValue(value);
            if (state > -1 && state < 3)
            {
                cell.setState(state);
            }
        }
        return this;
	}
	
    public MDataRow set(Object key, Object value)
    {
        return set(key, value, -1);
    }
	
	@Override
	public int size() {
		// TODO Auto-generated method stub
		return cellList.size();
	}

	@Override
	public List<MDataCell> subList(int fromIndex, int toIndex) {
		// TODO Auto-generated method stub
		return cellList.subList(fromIndex, toIndex);
	}

	@Override
	public Object[] toArray() {
		// TODO Auto-generated method stub
		return cellList.toArray();
	}

	@Override
	public <T> T[] toArray(T[] a) {
		// TODO Auto-generated method stub
		return cellList.toArray(a);
	}
}
